package com.cwf.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cwf.common.core.service.BaseService;
import com.cwf.common.enums.BaseStateEnum;
import com.cwf.common.enums.IsDeleteEnum;
import com.cwf.common.enums.ResCodeEnum;
import com.cwf.common.exception.base.MyException;
import com.cwf.framework.redis.RedisService;
import com.cwf.system.dao.PermissionDao;
import com.cwf.system.entity.Permission;
import com.cwf.system.service.PermissionService;
import com.cwf.system.vo.PermissionTreeVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * (Permission)表服务实现类
 *
 * @author makejava
 * @since 2023-02-15 15:49:36
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionDao, Permission> implements PermissionService {


    @Autowired
    private PermissionDao permissionDao;

    @Autowired
    RedisService redisService;


    List<PermissionTreeVO> permissionTreeVOList = new ArrayList<>();


    @Override
    public List<PermissionTreeVO> getPermissionTreeVO(Permission permission) {
        LambdaQueryWrapper<Permission> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper
                .like(permission.getTitle() != null,
                        Permission::getTitle,
                        permission.getTitle()
                )
                .eq(
                        permission.getRank()!=null,
                        Permission::getRank,
                        permission.getRank()

                )
                .eq(permission.getCategory() != null,
                        Permission::getCategory,
                        permission.getCategory()
                )
                .eq(
                        permission.getState() !=null,
                        Permission::getState,
                        permission.getState()
                )
                .eq(
                        permission.getIsShow() != null,
                        Permission::getIsShow,
                        permission.getIsShow()
                )
                .eq(Permission::getIsDelete, IsDeleteEnum.NO.getCode());
        List<Permission> permissions = permissionDao.selectList(lambdaQueryWrapper);

        if (permissions.size()==0){
            throw new MyException("未找到相关数据",ResCodeEnum.ERROR.getCode());
        }

        List<Long> idList1 = new ArrayList<>();

        permissions.forEach(v->{
            treeVO(permissionDao.byIdGetChildren(v.getId())).forEach(v1->{
                idList1.add(v1);
            });
        });

        List<Long> longList = idList1.stream().distinct().collect(Collectors.toList());

        LambdaQueryWrapper<Permission> lambdaQueryWrapper1 = new LambdaQueryWrapper<>();
        lambdaQueryWrapper1.in(Permission::getId,longList);

        return formatPageTree(PermissionTreeVO.toVOList(this.list(lambdaQueryWrapper1)));


    }


    public List<Long> treeVO(PermissionTreeVO list){

        List<PermissionTreeVO> list1 = new ArrayList<>();
        list1.add(list);

        List<PermissionTreeVO> children1 = list.getChildren();


        for (int i = 0; i < children1.size(); i++) {
            list1.add(children1.get(i));
            List<PermissionTreeVO> children2 = children1.get(i).getChildren();

            if (children2.size()>0){
               for (int j = 0; j< children2.size(); j++) {
                   list1.add(children2.get(j));
                   List<PermissionTreeVO> children3 = children2.get(j).getChildren();

                   if (children3.size()>0){
                       for (int k = 0; k < children3.size(); k++) {
                           list1.add(children3.get(k));

                           List<PermissionTreeVO> children4 = children3.get(k).getChildren();

                           if (children4.size()>0){
                               for (int l = 0; l < children4.size(); l++) {
                                   list1.add(children4.get(l));
                               }
                           }

                       }
                   }
               }
           }
        }

        List<Long> collect = list1.stream().map(v -> v.getId()).collect(Collectors.toList());

        return collect;

    }


    public static List<PermissionTreeVO> formatPageTree(List<PermissionTreeVO> list) {

        //找出级别最高的节点(数字越小级别越高)
        Integer minRank = list.stream().map(PermissionTreeVO::getRank).min(Comparator.comparing(v -> v)).get();

        Map<Long, PermissionTreeVO> permissionTreeDTOMap = list.stream().collect(Collectors.toMap(PermissionTreeVO::getId, v -> v));
        List<PermissionTreeVO> rootList = list.stream().filter(v -> Objects.equals(v.getRank(), minRank)).collect(Collectors.toList());
        list.forEach(v -> {
            if (permissionTreeDTOMap.containsKey(v.getParentId())) {
                List<PermissionTreeVO> children = permissionTreeDTOMap.get(v.getParentId()).getChildren();
                children.add(v);
            }
        });
        return rootList;
    }


    @Override
    public List<PermissionTreeVO> getAllPermissionTree() {

        LambdaQueryWrapper<Permission> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper
                .eq(Permission::getState, BaseStateEnum.OK.getCode())
                .eq(Permission::getIsDelete,IsDeleteEnum.NO.getCode())
                .orderByAsc(Permission::getRank,Permission::getSort);


        List<PermissionTreeVO> list = formatPageTree(PermissionTreeVO.toVOList(this.list(lambdaQueryWrapper)));

        if (list.size()==0){
            System.out.println(123);
        }
        return list;
    }

    @Override
    public Permission byIdGetPermissionInfo(Integer id) {

        LambdaQueryWrapper<Permission> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Permission::getId, id);

        Permission permission = permissionDao.selectOne(lambdaQueryWrapper);

        BaseService.checkByIdGetInfoResult(permission, "获取当前菜单/按钮失败");

        return permission;
    }






    @Override
    public boolean add(Permission permission) {


        LambdaQueryWrapper<Permission> lambdaQueryWrapper = new LambdaQueryWrapper<>();


        lambdaQueryWrapper.eq(Permission::getId, permission.getParentId());


        Permission permission1 = permissionDao.selectOne(lambdaQueryWrapper);


        switch (permission.getCategory()) {
            case 1:


                lambdaQueryWrapper
                        .eq(Permission::getPath, permission.getPath())
                        .eq(Permission::getName, permission.getName());

                break;

            case 2:
                lambdaQueryWrapper.eq(Permission::getPath, permission.getPath());
                break;

            case 3:

                lambdaQueryWrapper.eq(Permission::getMark, permission.getMark());

                break;
        }

        List<Permission> list = this.list(lambdaQueryWrapper);


        if (list.size() > 0 && permission.getCategory() == 3) {
            throw new MyException("此按钮标识已存在", ResCodeEnum.ERROR.getCode());
        } else if (list.size() > 0 && permission.getCategory() == 2) {
            throw new MyException("此目录路径已存在", ResCodeEnum.ERROR.getCode());
        } else if (list.size() > 0 && permission.getCategory() == 1) {
            throw new MyException("此菜单路由路径/路由名称已存在", ResCodeEnum.ERROR.getCode());
        }
        return this.save(permission);
    }

    @Override
    public boolean update(Permission permission) {
        return this.updateById(permission);
    }


    @Override
    public boolean delete(Integer id) {

        List<Permission> list = this.list(new LambdaQueryWrapper<Permission>()
                .eq(Permission::getParentId, id)
        );
        if (list.size()>0){
           throw new MyException("当前节点下还有子级菜单/按钮,不能删除",ResCodeEnum.DELETE_ERR.getCode());
        }

        Permission permission = Permission.builder()
                .id(Long.valueOf(id))
                .isDelete(IsDeleteEnum.OK.getCode()).build();

        return this.update(permission);
    }
}

